from netMessages import NetMessages
from netMsgService import NetMsgService
from room import Room
from user import User

NET_MESSAGES = NetMessages()
service = NetMsgService()

class NetMsgHandler:

    async def NM_LOGIN_handler(self, data, clientSocket, gameServer):
        print("User login username:{}, remote_address:{}".format(data["userName"], clientSocket.remote_address))


        userName = data["userName"]
        user = User(gameServer.getNextUserId(), userName, clientSocket)
        gameServer.login(clientSocket, user)

        response = {
            "user": user.toDTO()
        }
        await gameServer.sendMessage(NET_MESSAGES.NM_LOGIN_RESULT, response, clientSocket)

    
    async def NM_GET_ROOMLIST_handler(self, data, clientSocket, gameServer):
        response = {
            "rooms": gameServer.getRoomDTOs()
        }
        
        await gameServer.sendMessage(NET_MESSAGES.NM_GET_ROOMLIST_RESULT, response, clientSocket)
        
    
    async def NM_CREATEROOM_handler(self, data, clientSocket, gameServer):
        print("User createroom roomdesc:{}, remote_address:{}".format(data["roomDesc"], clientSocket.remote_address))

        roomDesc = data["roomDesc"]
        room = gameServer.createRoom(roomDesc)
        user = gameServer.getUser(clientSocket)
        user.setRoomMaster(True)
        gameServer.userJoinRoom(user, room)

        response = {
            "room": room.toDTO()
        }

        await gameServer.sendMessage(NET_MESSAGES.NM_CREATEROOM_RESULT, response, clientSocket)
        await gameServer.broadcastMessage(NET_MESSAGES.NM_ROOM_CHANGED, {})


    async def NM_JOINROOM_handler(self, data, clientSocket, gameServer):
        user = gameServer.getUser(clientSocket)
        room2Join = gameServer.getRoomById(data["roomId"])
        gameServer.userJoinRoom(user, room2Join)
        user.setRoomMaster(False)
        user.cancelReady()

        response = {
            "user": user.toDTO(),
            "room": room2Join.toDTO()
        }

        await gameServer.broadcastMessageRoomExcept(NET_MESSAGES.NM_JOINROOM_RESULT, response, room2Join, clientSocket)
        await gameServer.sendMessage(NET_MESSAGES.NM_JOINROOM_RESULT, response, clientSocket)
        

    async def NM_LEAVEROOM_handler(self, data, clientSocket, gameServer):
        roomId = data["roomId"]

        user = gameServer.getUser(clientSocket)
        room = gameServer.getRoomById(roomId)

        await service.userLeaveRoom(user, gameServer)

        response = {
            "user": user.toDTO(),
            "room" : room.toDTO()
        }
        
        await gameServer.sendMessage(NET_MESSAGES.NM_LEAVEROOM_RESULT, response, clientSocket)


    async def NM_GET_ROOMINFO_handler(self, data, clientSocket, gameServer):
        user = gameServer.getUser(clientSocket)
        room = user.getRoom()

        if room != None:
            response = {
                "room": room.toDTO()
            }
            await gameServer.sendMessage(NET_MESSAGES.NM_GET_ROOMINFO_RESULT, response, clientSocket)
        else:
            response = {
                "room": None
            }
            await gameServer.sendMessage(NET_MESSAGES.NM_GET_ROOMINFO_RESULT, response, clientSocket)


    async def NM_LOGOUT_handler(self, data, clientSocket, gameServer):
        gameServer.logout(clientSocket)
        await gameServer.sendMessage(NET_MESSAGES.NM_LOGOUT_RESULT, {}, clientSocket)
        

    async def NM_READY_handler(self, data, clientSocket, gameServer):
        user = gameServer.getUser(clientSocket)
        await service.userReady(user, gameServer)


    async def NM_CANCEL_READY_handler(self, data, clientSocket, gameServer):
        user = gameServer.getUser(clientSocket)
        await service.userCancelReady(user, gameServer)
    
        
    async def NM_START_GAME_handler(self, data, clientSocket, gameServer):
        user = gameServer.getUser(clientSocket)
        await service.gameStart(user, gameServer)
        

    async def NM_SEND_UPDATE_VIEW_handler(self, data, clientSocket, gameServer):
        blocksData = data["blocksData"]
        user = gameServer.getUser(clientSocket)
        room = user.getRoom()

        response = {
            "blocksData": blocksData,
            "user": user.toDTO()
        }

        await gameServer.broadcastMessageRoomExcept(NET_MESSAGES.NM_UPDATE_OTHER_PLAYER_VIEW, response, room, clientSocket)

        
    async def NM_USER_GAME_END_handler(self, data, clientSocket, gameServer):
        user = gameServer.getUser(clientSocket)
        room = user.getRoom()
        room.userGameEnd(user)

        print("User game end. room is gaming: {}, remote_address:{}".format(room.isGaming(), clientSocket.remote_address))

        response = {
            "user": user.toDTO()
        }
        await gameServer.broadcastMessageRoom(NET_MESSAGES.NM_USER_GAME_END_NOTIFY, response, room)

        if not room.isGaming():
             await gameServer.broadcastMessageRoom(NET_MESSAGES.NM_GAME_END, {}, room)

    
    async def NM_UPLOAD_SCORE_handler(self, data, clientSocket, gameServer):
        user = gameServer.getUser(clientSocket)
        await service.uploadScore(user, data["score"], gameServer)


    async def NM_GET_RANK_INFO_handler(self, data, clientSocket, gameServer):
        response = {
            "scoreInfo": service.getScoreInfo()
        }
        await gameServer.sendMessage(NET_MESSAGES.NM_GET_SCORE_INFO_RESULT, response, clientSocket)

    
    async def NM_SCORE_CHANGED_handler(self, data, clientSocket, gameServer):
        user = gameServer.getUser(clientSocket)
        room = user.getRoom()
        
        response = {
            "user": user.toDTO(),
            "score": data["score"]
        }
        await gameServer.broadcastMessageRoomExcept(NET_MESSAGES.NM_USER_SCORE_CHANGED, response, room, clientSocket)
    
        

    